package com.community.service.impl;

import com.community.annotation.SysLog;
import com.community.base.BaseService;
import com.community.common.Const;
import com.community.common.ServerResponse;
import com.community.pojo.Integral;
import com.community.pojo.IntegralLockRecord;
import com.community.pojo.IntegralRecord;
import com.community.service.IIntegralService;
import com.community.util.LoginUtil;
import com.community.util.NumberUtil;
import com.community.util.ToolUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.zookeeper.Login;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 积分服务层
 */
@Service("iIntegralService")
public class IntegralServiceImpl extends BaseService implements IIntegralService {

    /**
     * 查询用户剩余积分及
     * @param userName
     * @return
     */
    @SysLog("查询用户剩余积分")
    public ServerResponse<Integer> selectSurplusByUserName(String userName,HttpServletRequest request){
        if(!LoginUtil.isLogin(request,userName)){
            return ServerResponse.createByErrorMessage(Const.Msg.PARAMTERERROR);
        }
        return ServerResponse.createBySuccess(Const.Msg.SELECTSUCCESS,
                integralMapper.selectSurplusByUserName(userName));
    }


    /**
     * 交易方法
     * @param incomeUser 进账方
     * @param expenditureUser 出账方
     * @param nums 数目
     * @param inRemarks 进账备注
     *  @param expRemarks 出账备注
     * @return
     */
    @Transactional(rollbackFor = { Exception.class })//事物控制
    @SysLog("交易方法")
    public ServerResponse<String> transaction(String incomeUser,
                                               String expenditureUser,double nums,String inRemarks,
                                               String expRemarks){
        /**
         * 出账方操作start
         */
        //查询出账方锁定状态
        Integral expUser = integralMapper.selectByUserName(expenditureUser);
        if(null == expUser){
            return ServerResponse.createByErrorMessage(Const.Msg.PARAMTERERROR);
        }
        if(expUser.getLock() == Const.LockStatus.LOCK){//账户被锁定
            return ServerResponse.createByErrorMessage(Const.Msg.ACCOUNTABNORMALITY);
        }
        //判断出账方余额是否充足
        if(nums > expUser.getSurplus()){
            return ServerResponse.createByErrorMessage(Const.Msg.DEFICIENCY);
        }
        //锁定出账方账户
        expUser.setLock(Const.LockStatus.LOCK);
        if(integralMapper.updateByPrimaryKeySelective(expUser) <= 0){
            return ServerResponse.createByErrorMessage(Const.Msg.UPDATEERROR);
        }
        //添加锁定积分账户记录
        IntegralLockRecord ild = new IntegralLockRecord();
        ild.setType(Const.LockStatus.LOCK);//状态
        ild.setUsername(expUser.getUsername());//用户名
        ild.setSurplus(expUser.getSurplus());//锁定时积分
        if(integralLockRecordMapper.insert(ild) <= 0){
            throw new RuntimeException();
        }
        //扣除出账方余额
        double ep = expUser.getSurplus() - nums;
        expUser.setSurplus(ep);
        //解锁账户
        expUser.setLock(Const.LockStatus.UNLOCK);
        if(integralMapper.updateByPrimaryKeySelective(expUser) <= 0){
            throw new RuntimeException();
        }
        //添加解锁积分账户记录
        ild = new IntegralLockRecord();
        ild.setType(Const.LockStatus.UNLOCK);//状态
        ild.setUsername(expUser.getUsername());//用户名
        ild.setSurplus(expUser.getSurplus());//解锁时积分
        if(integralLockRecordMapper.insert(ild) <= 0){
            throw new RuntimeException();
        }
        //添加出账方积分交易记录
        IntegralRecord expRecord = new IntegralRecord();
        expRecord.setIncomeAccount(incomeUser);//进账用户名
        expRecord.setExpenditureAccount(expenditureUser);//出账用户名
        expRecord.setIntegralNum(NumberUtil.safeToDouble(nums));//数目
        expRecord.setType(Const.Algorithm.MINUS);//支出
        expRecord.setTimes(new Date());//时间
        expRecord.setOddnumbers(ToolUtil.randomNumber());//流水单号
        expRecord.setSurplus(NumberUtil.safeToDouble(expUser.getSurplus()));//剩余积分
        expRecord.setRemarks(expRemarks);//出账备注
        if(integralRecordMapper.insert(expRecord) <= 0){
            throw new RuntimeException();
        }
        /**
         * 出账方操作end
         */

        /**
         * 进账方操作start
         */
        Integral inUser = integralMapper.selectByUserName(incomeUser);
        if(inUser == null){
            throw new RuntimeException();
        }
        //增加数目
        double ic = inUser.getSurplus()+nums;
        inUser.setSurplus(ic);
        if(integralMapper.updateByPrimaryKeySelective(inUser) <= 0){
            throw new RuntimeException();
        }
        //添加进账方积分交易记录
        IntegralRecord inRecord = new IntegralRecord();
        inRecord.setIncomeAccount(incomeUser);//进账用户名
        inRecord.setExpenditureAccount(expenditureUser);//出账用户名
        inRecord.setIntegralNum(NumberUtil.safeToDouble(nums));//数目
        inRecord.setType(Const.Algorithm.ADD);//收入
        inRecord.setTimes(new Date());//时间
        inRecord.setOddnumbers(ToolUtil.randomNumber());//流水单号
        inRecord.setSurplus(NumberUtil.safeToDouble(inUser.getSurplus()));//剩余积分
        inRecord.setRemarks(inRemarks);//出账备注
        if(integralRecordMapper.insert(inRecord) <= 0){
            throw new RuntimeException();
        }
        /**
         * 进账方操作end
         */
        return ServerResponse.createBySuccessMessage(Const.Msg.SAVESUCCESS);
    }

    /**
     * 查询用户交易记录
     * @param pageNum 页码
     * @param order 排序
     * @param userName 用户名
     * @return
     */
    public ServerResponse<PageInfo> selectIntegralByUserName(int pageNum,String order,String userName){
        PageHelper.startPage(pageNum,Const.MAXSIZE,order);
        List<Map> resultList = integralRecordMapper.selectByUserName(userName);
        if(null != resultList){
            PageInfo pageInfo = new PageInfo(resultList);
            return ServerResponse.createBySuccess(Const.Msg.SELECTSUCCESS,pageInfo);
        }
        return ServerResponse.createByErrorMessage(Const.Msg.SELECTERROR);
    }

}
